package p.ithorns.sample.websocket.core;

import io.netty.channel.Channel;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
import org.yeauty.annotation.*;
import org.yeauty.pojo.Session;
import p.ithorns.framework.common.utils.JsonUtil;
import p.ithorns.framework.common.utils.StringUtil;
import p.ithorns.framework.core.message.MsgPublisher;
import p.ithorns.framework.core.model.PubPacket;
import p.ithorns.sample.websocket.model.WsMsgType;
import p.ithorns.sample.websocket.model.WsUpMsg;

import java.util.Arrays;
import java.util.Map;

/**
 * GateDebugWsEndpoint
 *
 * @author Ht.L
 * @date 2023-06-19 10:22
 * @since 1.0.0
 */
@Slf4j
@ServerEndpoint(path = "${app.ws.path}", port = "${app.ws.port}")
public class WsEndpoint {

    // 分布式发布
    @Autowired
    private MsgPublisher msgPublisher;

    static {
        WsMsgType.register("DT", WsUpMsg.class);
    }

    private static final String CLIENT_ID = "CLIENT_ID";

    @BeforeHandshake
    public void handshake(Session session, HttpHeaders headers,
                          @RequestParam String req,
                          @RequestParam MultiValueMap reqMap,
                          @PathVariable String arg,
                          @PathVariable Map pathMap) {
        String subProtocols = headers.get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL);
        if (StringUtil.isBlank(subProtocols)) {
            log.warn("Authentication failed!");
            session.close();
        }

        // Protocols参数：1-客户端ID
        String[] protocols = StringUtil.split(subProtocols, ",");
        if (protocols.length < 1) {
            log.warn("WebSocket参数缺失:{}", Arrays.toString(protocols));
            session.close();
            return;
        }

        session.setSubprotocols(subProtocols);
        session.setAttribute(CLIENT_ID, protocols[0]);
    }

    @OnOpen
    public void onOpen(Session session, HttpHeaders headers) {
        Channel channel = session.channel();
        log.info("WebSocket 打开连接：{}", channel);

        final String wsClientChId = getWsChId(session);

        // 注册客户端Channel
        ChannelSupervise.register(wsClientChId, channel);

        // 发送一条消息
        ChannelSupervise.send(wsClientChId, "Hello!");
        // 初始化客户端参数
        // wsCache.initClientParam(token);
    }


    @OnMessage
    public void onMessage(Session session, String message) {
        log.info(message);

        try {
            // 解析和处理消息
            WsUpMsg<?> msg = JsonUtil.fromJson(message, WsUpMsg.class);
            if (null != msg) {
                final String clientId = getWsChId(session);
                msg.setClientId(clientId);

                PubPacket<?> packet = PubPacket.create(msg.getType(), msg);
                msgPublisher.publish(packet);
                // WsMsgHandlerDelegate.handle(msg);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }


    @OnClose
    public void onClose(Session session) {
        Channel channel = session.channel();
        log.info("Session closed: {}", channel);
        ChannelSupervise.removeChannel(channel);
        // String clientId = session.getAttribute(CLIENT_ID);
        // wsCache.removeClientParam(clientId);
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        log.error("Locate WebSocket err1or.", throwable);
        session.close();
    }

    private String getWsChId(Session session) {
        final String client = session.getAttribute(CLIENT_ID);
        return client + ":" + session.id().asShortText();
    }

}